﻿using System;
using System.Threading;
using System.Windows.Forms;
using AiFrame.Base.Core;
using AiFrame.Base.Core.MVP;
using AiFrame.Base.Core.Plugins;
using AiFrame.Base.WinUI.MVP;
using AiFrame.Base.WinUI.Windows.UI;
using AiFrame.InterfaceLib.Configuration;
using AiFrame.InterfaceLib.Logs;
using AiFrame.InterfaceLib.Plugins;

namespace AiFrame.Base.WinUI
{
    /// <summary>
    /// Initializations
    /// </summary>
    public class BaseInitialization
    {
        private string[] args;
        private bool configurationMode = false;
        private MainWindowView wnd;
        private static IPluginManager pm;

        public BaseInitialization(string[] args)
        {
            this.args = args;

            if (args.Length > 0)
                configurationMode = true;
        }

        public bool IsConfigurationMode()
        {
            return configurationMode;
        }

        /// <summary>
        /// Gets the plugin manager.
        /// </summary>
        public static IPluginManager PluginManager
        {
            get
            {
                return pm;
            }
        }
            

        public void PostInitialize(IStartupView loginView)
        {
            if (configurationMode)
            {
                try
                {
                    LogHandler.GetLogger().Debug("Load Configuation Module...");
                    IStartupConfiguration configuration = PluginManagerLoader.Instance()
                        .GetPluginManager().LoadConfigurationModule(args[0]);

                    LogHandler.GetLogger().Debug("Start Configuration...");
                    configuration.Configure();
                    loginView.DisplayError("Konfiguration wurde erfolgreich durchgeführt!");
                }
                catch (Exception e)
                {
                    loginView.DisplayError(e.Message + Environment.NewLine + e.StackTrace);
                }
                finally
                {
                    Application.Exit();
                }
            }
            else
            {
                Application.Run(wnd);
            }
        }
        

        public void PreInitialize()
        {
            Factories.ComponentFactory = new DefaultComponentFactory();

            /************************************************************
            * Exception Handling */
            Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);

            // Alle unbehandelten WinForms-Fehler durch diesen Ereignis-Handler 
            // zwingen (unabhängig von config-Einstellungen):
            Application.SetUnhandledExceptionMode(
                UnhandledExceptionMode.CatchException);

            // Ereignis-Hanlder für nicht UI-Threads:
            AppDomain.CurrentDomain.UnhandledException +=
                new UnhandledExceptionEventHandler(
                    CurrentDomain_UnhandledException);


            /*************************************************************/

            /* PluginManagerLoader initialisieren und anschließend
                 * die Plugins laden */
            pm = PluginManagerLoader.Instance().LoadPluginManager(Application.StartupPath);
            pm.LoadSystemLibraries();
            

            wnd = new MainWindowView();
            
            ToolBarManager.Instance.Init(wnd.ToolPanel, TabSetManager.Instance());
            wnd.RegisterMainToolPanel();


            /* Nun sollen die Plugins geladen werden */
            pm.Init(new CoreInterfaceFactory(TabSetManager.Instance(), wnd.GetNavBar(),
                                             new StyleGuideUI(), ToolBarManager.Instance, wnd));
            pm.LoadPlugins(Application.StartupPath);

            IBaseFactory baseFactory = new BaseFactory()
            {
                TabSetManager = TabSetManager.Instance()
            };
            wnd.BaseFactory = baseFactory;
        }

        private static void ShowErrorDialog(Exception e)
        {
            ReportErrorWindow reportErrorWindow = new ReportErrorWindow(e);
            reportErrorWindow.ShowDialog();
        }

        private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            ShowErrorDialog(e.ExceptionObject as Exception);
        }

        private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
        {
            ReportErrorWindow reportErrorWindow = new ReportErrorWindow(e.Exception);
            reportErrorWindow.ShowDialog();
        }
    }
}
